package com.tianzj.mvc.system.shiro;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import com.tianzj.mvc.system.pojo.SysMenu;
import com.tianzj.mvc.system.pojo.SysRoleMenu;
import com.tianzj.mvc.system.pojo.SysUser;
import com.tianzj.mvc.system.pojo.SysUserRole;
import com.tianzj.mvc.system.service.SysMenuService;
import com.tianzj.mvc.system.service.SysRoleMenuService;
import com.tianzj.mvc.system.service.SysUserRoleService;
import com.tianzj.mvc.system.service.SysUserService;
import com.tianzj.util.MD5Utils;

/**
 * Created with IntelliJ IDEA.
 * Description: 自定义reaml
 * User: liubin
 * Date: 2017-11-02
 * Time: 上午 9:30
 */
public class UserRealm extends AuthorizingRealm{

	@Autowired
	private SysUserRoleService sysUserRoleService;
	@Autowired
	private SysRoleMenuService sysRoleMenuService;
	@Autowired
	private SysMenuService sysMenuService;
	@Autowired
	private SysUserService sysUserService;

    /**
     * 授权
     * 如果效率慢，需在实体中增加set属性
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SysUser user = (SysUser) principals.fromRealm(this.getClass().getName()).iterator().next();
        List<String> authCodes = new ArrayList<String>();
        List<SysUserRole> sysUserRoles = sysUserRoleService.getUserRoleByUserId(user.getId());
        if(sysUserRoles.size()>0){
            for (SysUserRole userRole : sysUserRoles){
                List<SysRoleMenu> sysRoleMenus = sysRoleMenuService.getRoleMenuByRoleId(userRole.getRoleId());
                if(sysRoleMenus.size()>0){
                	SysMenu  sysMenu;
                    for(SysRoleMenu roleMenu : sysRoleMenus){
                    	sysMenu =sysMenuService.getMenuById(roleMenu.getMenuId());
                        if(sysMenu!=null&&StringUtils.isNotBlank(sysMenu.getAuthCode())){
                        	authCodes.add(sysMenu.getAuthCode());
                        }
                    }
                }
            }
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //将权限放入shiro中
        info.addStringPermissions(authCodes);
        return info;
    }


    /**
     * 认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken utoken = (UsernamePasswordToken) token;
        String uname = utoken.getUsername();
        SysUser userNew = new SysUser();
        userNew.setUserName(uname);
        SysUser sysUser = sysUserService.getByUserNameAndPass(userNew);
        if(sysUser!=null){
            Subject currentUser = SecurityUtils.getSubject();
            Session session = currentUser.getSession();
            //剔除用户(暂时NO)
            session.setAttribute("session_user", sysUser);
            //放入shiro供CredentialsMatcher检验密码
            return new SimpleAuthenticationInfo(sysUser,sysUser.getPassword(),this.getClass().getName());
        }
        //exception
        return  null;
    }

    	public static void main(String[] args) {
        String hashAlgorithmName = "MD5";
        String credentials = "123456";
        int hashIterations = 1024;
        Object obj = new SimpleHash(hashAlgorithmName, credentials, null, hashIterations);
        System.out.println(obj);
    }

}
